home *** CD-ROM | disk | FTP | other *** search
/ Reverse Code Engineering RCE CD +sandman 2000 / ReverseCodeEngineeringRceCdsandman2000.iso / RCE / Library / Manuels & Misc / Assembly / AOA.ZIP / CH16 / ARITH.ASM next >
Encoding:
Assembly Source File  |  1994-07-09  |  3.5 KB  |  234 lines

  1. ; ARITH.ASM
  2. ;
  3. ; A simple recursive descent parser for arithmetic strings.
  4.  
  5.         .xlist
  6.         include     stdlib.a
  7.         includelib    stdlib.lib
  8.         .list
  9.  
  10.  
  11. dseg        segment    para public 'data'
  12.  
  13. ; Grammar for simple arithmetic grammar (supports +, -, *, /):
  14. ;
  15. ; E -> FE'
  16. ; E' -> + F E' | - F E' | <empty string>
  17. ; F -> TF'
  18. ; F' -> * T F' | / T F' | <empty string>
  19. ; T -> G | (E)
  20. ; G -> H | H G
  21. ; H -> 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
  22. ;
  23.  
  24.  
  25. InputLine    byte    128 dup (0)
  26.  
  27. dseg        ends
  28.  
  29. cseg        segment    para public 'code'
  30.         assume    cs:cseg, ds:dseg
  31.  
  32. ; Matching functions for the grammar.
  33. ; These functions return the carry flag set if they match their
  34. ; respective item.  They return the carry flag clear if they fail.
  35. ; If they fail, they preserve di.  If they succeed, di points to
  36. ; the first character after the match.
  37.  
  38.  
  39. ; E -> FE'
  40.  
  41. E        proc    near
  42.         push    di
  43.         call    F
  44.         jnc    E_Failed
  45.         call    EPrime
  46.         jnc    E_Failed
  47.         add    sp, 2        ;Success, don't restore di.
  48.         stc
  49.         ret
  50.  
  51. E_Failed:    pop    di
  52.         clc
  53.         ret
  54. E        endp
  55.  
  56.  
  57.  
  58. ; E' -> + F E' | - F E' | <empty string>
  59.  
  60. EPrime        proc    near
  61.         push    di
  62.         cmp    byte ptr es:[di], '+'
  63.         jne    TryMinus
  64.         inc    di
  65.         call    F
  66.         jnc    EP_Failed
  67.         call    EPrime
  68.         jnc    EP_Failed
  69. Success:    add    sp, 2
  70.         stc
  71.         ret
  72.  
  73. TryMinus:    cmp    byte ptr es:[di], '-'
  74.         jne    Success
  75.         inc    di
  76.         call    F
  77.         jnc    EP_Failed
  78.         call    EPrime
  79.         jnc    EP_Failed
  80.         add    sp, 2
  81.         stc
  82.         ret
  83.  
  84. EP_Failed:    pop    di
  85.         stc
  86.         ret
  87. EPrime        endp
  88.  
  89.  
  90.  
  91. ; F -> TF'
  92.  
  93. F        proc    near
  94.         push    di
  95.         call    T
  96.         jnc    F_Failed
  97.         call    FPrime
  98.         jnc    F_Failed
  99.         add    sp, 2        ;Success, don't restore di.
  100.         stc
  101.         ret
  102.  
  103. F_Failed:    pop    di
  104.         clc
  105.         ret
  106. F        endp
  107.  
  108.  
  109.  
  110.  
  111. ; F -> * T F' | / T F' | <empty string>
  112.  
  113. FPrime        proc    near
  114.         push    di
  115.         cmp    byte ptr es:[di], '*'
  116.         jne    TryDiv
  117.         inc    di
  118.         call    T
  119.         jnc    FP_Failed
  120.         call    FPrime
  121.         jnc    FP_Failed
  122. Success:    add    sp, 2
  123.         stc
  124.         ret
  125.  
  126. TryDiv:        cmp    byte ptr es:[di], '/'
  127.         jne    Success
  128.         inc    di
  129.         call    T
  130.         jnc    FP_Failed
  131.         call    FPrime
  132.         jnc    FP_Failed
  133.         add    sp, 2
  134.         stc
  135.         ret
  136.  
  137. FP_Failed:    pop    di
  138.         stc
  139.         ret
  140. FPrime        endp
  141.  
  142.  
  143. ; T -> G | (E)
  144.  
  145. T        proc    near
  146.         call    G
  147.         jnc    TryParens
  148.         ret
  149.  
  150. TryParens:    push    di
  151.         cmp    byte ptr es:[di], '('
  152.         jne    T_Failed
  153.         inc    di
  154.         call    E
  155.         jnc    T_Failed
  156.         cmp    byte ptr es:[di], ')'
  157.         jne    T_Failed
  158.         inc    di
  159.         add    sp, 2
  160.         stc
  161.         ret
  162.  
  163. T_Failed:    pop    di
  164.         clc
  165.         ret
  166. T        endp
  167.  
  168.  
  169. ; The following is a free-form translation of
  170. ;
  171. ; G -> H | H G
  172. ; H -> 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
  173.  
  174. G        proc    near
  175.         cmp    byte ptr es:[di], '0'
  176.         jb    G_Failed
  177.         cmp    byte ptr es:[di], '9'
  178.         ja    G_Failed
  179.  
  180. DigitLoop:    inc    di
  181.         cmp    byte ptr es:[di], '0'
  182.         jb    G_Succeeds
  183.         cmp    byte ptr es:[di], '9'
  184.         jbe    DigitLoop
  185. G_Succeeds:    stc
  186.         ret
  187.  
  188. G_Failed:    clc
  189.         ret
  190. G        endp
  191.  
  192.  
  193. Main        proc
  194.         mov    ax, seg dseg        ;Set up the segment registers
  195.         mov    ds, ax
  196.         mov    es, ax
  197.  
  198.         printf
  199.         byte    "Enter an arithmetic expression: ",0
  200.         lesi    InputLine
  201.         gets
  202.         call    E
  203.         jnc    BadExp
  204.  
  205. ; Good so far, but are we at the end of the string?
  206.  
  207.         cmp    byte ptr es:[di], 0
  208.         jne    BadExp
  209.  
  210. ; Okay, it truly is a good expression at this point.
  211.  
  212.         printf
  213.         byte      "'%s' is a valid expression",cr,lf,0
  214.         dword    InputLine
  215.         jmp    Quit
  216.  
  217. BadExp:        printf
  218.         byte    "'%s' is an invalid arithmetic expression",cr,lf,0
  219.         dword    InputLine
  220.  
  221. Quit:        ExitPgm
  222. Main        endp
  223.  
  224. cseg            ends
  225.  
  226. sseg        segment    para stack 'stack'
  227. stk        byte    1024 dup ("stack   ")
  228. sseg        ends
  229.  
  230. zzzzzzseg    segment    para public 'zzzzzz'
  231. LastBytes    byte    16 dup (?)
  232. zzzzzzseg    ends
  233.         end    Main
  234.